package interview.juc;

/**
 * 1.创建资源类，新建属性和操作资源的方法
 * 2.在资源类操作方法
 *  2.1判断
 *  2.2干活
 *  2.3唤醒
 * 3.创建线程多个线程，调用资源类操作方法
 * 4.防止虚假唤醒
 * 线程间通信  synchronized实现
 */
class Correspond{
    private int num;

    public synchronized void add() throws InterruptedException {
        /**
         * 使用if会有虚假唤醒，需要使用while
         */
        while(num != 0){
            this.wait();
        }
        num++;
        System.out.println(Thread.currentThread().getName()+" add :"+num);
        this.notifyAll();
    }
    public synchronized void decr() throws InterruptedException {
        while(num != 1){
            this.wait();
        }
        num--;
        System.out.println(Thread.currentThread().getName()+" decr :"+num);
        this.notifyAll();
    }
}
public class Juc03_01 {
    public static void main(String[] args) {
        Correspond correspond = new Correspond();
        new Thread(()->{
            for (int i = 0; i < 20; i++) {
                try {
                    correspond.add();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        },"A").start();
        new Thread(()->{
            for (int i = 0; i < 20; i++) {
                try {
                    correspond.decr();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        },"B").start();
        new Thread(()->{
            for (int i = 0; i < 20; i++) {
                try {
                    correspond.add();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        },"C").start();
        new Thread(()->{
            for (int i = 0; i < 20; i++) {
                try {
                    correspond.decr();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        },"D").start();
    }
}
